import 'dart:async';

/**
 *
 * @Description:     地图widget 此地图与原生Android / ios 打通，如需更改，请联系Author
 * @Author:          胡凯
 * @CreateDate:      2020-08-14
 * @Version:         1.0
 *
 */
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';

import 'amap_controller.dart';
import 'model/amap_options.dart';

typedef void MapCreatedCallback(AMapController controller);

const _viewType = "com.p595263720.zit/GD";

class AMapView extends StatefulWidget {
  final MapCreatedCallback onAMapViewCreated;
  final PlatformViewHitTestBehavior hitTestBehavior;
  final TextDirection layoutDirection;
  final AMapOptions aMapOptions;

  /// [PlatformView]创建时, 会有一下的黑屏, 这里提供一个在[PlatformView]初始化时, 盖住其黑屏
  /// 的遮罩, [maskDelay]配置延迟多少时间之后再显示地图, 默认不延迟, 即0.
  final Duration maskDelay;

  /// 遮盖地图层的widget
  final Widget mask;

  const AMapView({
    Key key,
    this.onAMapViewCreated,
    this.hitTestBehavior = PlatformViewHitTestBehavior.opaque,
    this.layoutDirection,
    this.aMapOptions = const AMapOptions(),
    this.maskDelay = const Duration(milliseconds: 500),
    this.mask,
  }) : super(key: key);

  @override
  AmapViewState createState() => AmapViewState();
}

class AmapViewState extends State<AMapView> {
  Widget _mask = Container(
    color: Colors.white,
    child: Center(),
  );
  Widget _widgetLayer;

  @override
  void initState() {
    super.initState();
    _mask = FutureBuilder<bool>(
      future: Future.delayed(widget.maskDelay, () => false),
      initialData: true,
      builder: (context, snapshot) {
        return Visibility(
          visible: snapshot.data,
          child: widget.mask ??
              Container(
                color: Colors.white,
                child: Center(child: CupertinoActivityIndicator()),
              ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    final gestureRecognizers = <Factory<OneSequenceGestureRecognizer>>[
      Factory<OneSequenceGestureRecognizer>(() => EagerGestureRecognizer()),
    ].toSet();

    final String params = jsonEncode(widget.aMapOptions.toJson());
    final messageCodec = StandardMessageCodec();
    // TODO: implement build
    if (Platform.isAndroid) {
      return Stack(
          children: <Widget>[
            if (_widgetLayer != null) _widgetLayer,
            AndroidView(
                viewType: _viewType,
                //传递给native侧，用于view factory的key
                onPlatformViewCreated: _onViewCreated,
                //创建成功回调，注意回调参数是viewId，通常会在这里初始化Controller，并将controller作为上面MapView onCreateCallback的参数。这样子外部在使用MapView这个widget的时候，就能够拿到其对应的Controller
                creationParams: params,
                //传递给原生的初始化参数
                creationParamsCodec: messageCodec,
                hitTestBehavior: widget.hitTestBehavior,
                gestureRecognizers: gestureRecognizers,
                layoutDirection: widget.layoutDirection
            ),
            _mask
          ],
      );
    } else if (Platform.isIOS) {
      return Stack(
        children: <Widget>[
          if (_widgetLayer != null) _widgetLayer,
          UiKitView(
              viewType: _viewType,
              //传递给native侧，用于view factory的key
              onPlatformViewCreated: _onViewCreated,
              //创建成功回调，注意回调参数是viewId，通常会在这里初始化Controller，并将controller作为上面MapView onCreateCallback的参数。这样子外部在使用MapView这个widget的时候，就能够拿到其对应的Controller
              creationParams: params,
              //传递给原生的初始化参数
              creationParamsCodec: messageCodec,
              hitTestBehavior: widget.hitTestBehavior,
              gestureRecognizers: gestureRecognizers,
              layoutDirection: widget.layoutDirection
          ),
          _mask
        ],
      );
    } else {
      return Text('此平台不支持高德地图');
    }
  }

  void _onViewCreated(int id) {
    final controller = AMapController.withId(id, this);
    if (widget.onAMapViewCreated != null) {
      widget.onAMapViewCreated(controller);
    }
  }

  Future<List<Uint8List>> widgetToImageData(List<Widget> markerList) {
    final completer = Completer<List<Uint8List>>();
    final ratio = MediaQuery.of(context).devicePixelRatio;

    final globalKeyList = <GlobalKey>[];
    for (int i = 0; i < markerList.length; i++) globalKeyList.add(GlobalKey());

    setState(() {
      _widgetLayer = Stack(
        children: [
          for (int i = 0; i < markerList.length; i++)
            RepaintBoundary(key: globalKeyList[i], child: markerList[i])
        ],
      );
    });

    // 等待一帧结束再获取图片数据
    WidgetsBinding.instance.addPostFrameCallback((duration) async {
      final result = <Uint8List>[];

      await Future.wait([
        for (final key in globalKeyList)
          (key.currentContext.findRenderObject() as RenderRepaintBoundary)
              .toImage(pixelRatio: ratio)
              .then((image) => image.toByteData(format: ImageByteFormat.png))
              .then((byteData) => byteData.buffer.asUint8List())
              .then((data) => result.add(data))
      ]);

      completer.complete(result);

      // 清空
      setState(() {
        _widgetLayer = null;
      });
    });

    return completer.future;
  }
}
